package com.mucd.chat.utils;

import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.Session;
import java.util.List;
import java.util.Map;

/**
 * @author mucd
 */
@Component
@Slf4j
public class SocketUtils {
    @Resource
    private RedisCache redisCache;

    /**
     * 通过session获取用户信息
     * @param session session
     * @return loginUser
     */
    public LoginUser getLoginUser(Session session) {
        Map<String, List<String>> params = session.getRequestParameterMap();
        String authorization = params.get("Authorization").get(0);
        LoginUser loginUser = this.verifySaveLoginUser(authorization);

        return loginUser;
    }

    /**
     * @param session
     * @return
     */
    public LoginUser getValidatedLoginUser(Session session) {
        // 直接从Session中获取Authorization头信息
        Object authorizationHeader = session.getUserProperties().get("authorization");

        if (authorizationHeader == null) {
            throw new ServiceException("Authorization header not found, please re-login", HttpStatus.UNAUTHORIZED);
        }

        try {
            // 解析JWT并获取payload
            JWTPayload payload = JWTUtil.parseToken(authorizationHeader.toString()).getPayload();

            // 提取login_user_key
            String loginUserKey = payload.getClaimsJson().get("login_user_key", String.class);

            // 从Redis缓存中查询登录用户信息
            LoginUser loginUser = retrieveLoginUserFromCache(loginUserKey);

            if (loginUser == null) {
                throw new ServiceException("登录过期，请重新登录", HttpStatus.UNAUTHORIZED);
            }

            return loginUser;
        } catch (Exception e) {
            log.error("Failed to validate and fetch the login user from the JWT token or cache.", e);
            throw new ServiceException("无法验证登录信息，请重新登录", HttpStatus.UNAUTHORIZED);
        }
    }

    private LoginUser retrieveLoginUserFromCache(String loginUserKey) {
        String cacheKey = CacheConstants.LOGIN_TOKEN_KEY + loginUserKey;
        LoginUser cachedData = redisCache.getCacheObject(cacheKey);

        // 假设缓存中的数据可以直接反序列化为LoginUser对象
        return cachedData;
    }

    /**
     * 验证保存用户信息
     *
     * @param authorization token
     */
    public LoginUser verifySaveLoginUser(String authorization) {
        // 解析JWT并获取payload
        JWTPayload payload = JWTUtil.parseToken(authorization).getPayload();

        // 提取login_user_key
        String loginUserKey = payload.getClaimsJson().get("login_user_key", String.class);

        // 从Redis缓存中查询登录用户信息
        LoginUser loginUser = retrieveLoginUserFromCache(loginUserKey);

        if (loginUser == null) {
            throw new ServiceException("登录过期，请重新登录", HttpStatus.UNAUTHORIZED);
        }

        redisCache.setCacheObject(CacheConstants.LOGIN_USER_ID + loginUser.getUserId(), loginUser);

        return loginUser;
    }


    /**
     * 使用CacheConstants.LOGIN_USER_ID + userid从redis获取用户信息
     *
     * @param userId 用户id
     * @return 用户信息
     */
    public LoginUser getLoginUser(Long userId) {
        LoginUser loginUser = redisCache.getCacheObject(CacheConstants.LOGIN_USER_ID + userId);
        return loginUser;
    }

}
